#include "message.h"
#include <QByteArrayMatcher>
#include <QDebug>

const QByteArray Message::DSC_START = "<STX><MSG_START>,<DATA_START><ETX>";
const QByteArray Message::DSC_STOP = "<STX><MSG_STOP><ETX>";
const QByteArray Message::DSC_STATUS_READY = "<STX><MSG_STATUS_READY><ETX>";
const QByteArray Message::DSC_STATUS_WORKING = "<STX><MSG_STATUS_WORKING><ETX>";
const QByteArray Message::DSC_STATUS_DONE = "<STX><MSG_STATUS_DONE><ETX>";
const QByteArray Message::DSC_PROGRESS = "<STX><MSG_PROGRESS>,<INT_VALUE><ETX>";
const QByteArray Message::DSC_DISC_DATA = "<STX><MSG_DISC_DATA>,<DATA_DISC_DATA_1>,...,<DATA_DISC_DATA_N><ETX>";
const QByteArray Message::DSC_MOVIE_DATA = "<STX><MSG_MOVIE_DATA>,<DATA_MOVIE_DATA_1>,...,<DATA_MOVIE_DATA_N><ETX>";
const QByteArray Message::DSC_DISC_DATA_UNKNOWN = "<STX><MSG_DISC_DATA_UNKNOWN><ETX>";
const QByteArray Message::DSC_MOVIE_DATA_UNKNOWN = "<STX><MSG_MOVIE_DATA_UNKNOWN><ETX>";
const QByteArray Message::DSC_SEARCH_MOVIE_DATA = "<STX><MSG_SEARCH_MOVIE_DATA>,<DATA_MOVIE_DATA><ETX>";
const QByteArray Message::DSC_SEARCH_DISC_TITLE_DATA = "<STX><MSG_SEARCH_DISC_TITLE_DATA><CTRL_RS>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT><CTRL_US>TYPE=<DATA_TYPE><ETX>";

const QByteArray Message::DATA_DISC_DATA = "ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT><CTRL_US>RIPPED=<VALUE>";
const QByteArray Message::DATA_MOVIE_DATA = "ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT><CTRL_US>YEAR=<TEXT><CTRL_US>RIPPED=<VALUE>";
const QByteArray Message::DATA_START = "<STX><MSG_START><CTRL_RS><DATA_START><ETX>";

//Message::Message()
//{
//}

QList<QByteArray> Message::getAllMessages()
{
    QList<QByteArray> messageList;
    messageList.append(Message::DSC_START);
    messageList.append(Message::DSC_STOP);
    messageList.append(Message::DSC_STATUS_READY);
    messageList.append(Message::DSC_STATUS_WORKING);
    messageList.append(Message::DSC_STATUS_DONE);
    messageList.append(Message::DSC_PROGRESS);
    messageList.append(Message::DSC_DISC_DATA);
    messageList.append(Message::DSC_MOVIE_DATA);
    messageList.append(Message::DSC_DISC_DATA_UNKNOWN);
    messageList.append(Message::DSC_MOVIE_DATA_UNKNOWN);
    messageList.append(Message::DSC_SEARCH_MOVIE_DATA);
    messageList.append(Message::DSC_SEARCH_DISC_TITLE_DATA);
    return messageList;
}
QByteArray Message::getProgressMessage(int progress)
{
    QByteArray message;
    message.append(Message::CTRL_STX);
    message.append(Message::MSG_PROGRESS);
    message.append(Message::CTRL_RS);
    message.append(QString::number(progress));
    message.append(Message::CTRL_ETX);
    return message;
}
QByteArray Message::getDiscDataMessage(QList<DiscData> discDataList)
{
    //"<STX><MSG_DISC_DATA><CTRL_RS><DATA_DISC_DATA_1><CTRL_RS>...<CTRL_RS><DATA_DISC_DATA_N><ETX>";
    QByteArray message;
    QListIterator<DiscData> it(discDataList);
    message.append(Message::CTRL_STX);
    message.append(Message::MSG_DISC_DATA);
    while(it.hasNext())
    {
        DiscData discData = it.next();
        message.append(Message::CTRL_RS);
        message.append(Message::makeDataDisc(discData));
    }
    message.append(Message::CTRL_ETX);
    return message;
}
QByteArray Message::getMovieDataMessage(QList<MovieData> movieDataList)
{
    //"<STX><MSG_MOVIE_DATA>,<DATA_MOVIE_DATA_1>,...,<DATA_MOVIE_DATA_N><ETX>";
    QByteArray message;
    QListIterator<MovieData> it(movieDataList);
    message.append(Message::CTRL_STX);
    message.append(Message::MSG_MOVIE_DATA);
    while(it.hasNext())
    {
        MovieData movieData = it.next();
        message.append(Message::CTRL_RS);
        message.append(Message::makeMovieDisc(movieData));

    }
    message.append(Message::CTRL_ETX);
    return message;
}

QByteArray Message::makeDataDisc(Disc disc)
{
    //"IDA=<TEXT><CTRL_GS>IDB=<TEXT><CTRL_GS>NAME=<TEXT>";
    QByteArray message;
    message.append(QString("IDA"));
    message.append(Message::CTRL_EQUAL);
    message.append(disc.discIdSideA);

    message.append(Message::CTRL_GS);
    message.append(QString("IDB"));
    message.append(Message::CTRL_EQUAL);
    message.append(disc.discIdSideB);

    message.append(Message::CTRL_GS);
    message.append(QString("NAME"));
    message.append(Message::CTRL_EQUAL);
    message.append(disc.name);

    return message;
}

QByteArray Message::makeDataDiscs(Discs discs)
{
    //"<CTRL_FS><DATA_DISC_1>...<CTRL_FS><DATA_DISC_N><CTRL_FS>";
    QByteArray message;
    QListIterator<Disc> it(discs);
    while(it.hasNext())
    {
        Disc disc = it.next();
        message.append(Message::CTRL_FS);
        message.append(makeDataDisc(disc));
    }
    message.append(Message::CTRL_FS);
    return message;

}

QByteArray Message::makeDataDiscTitle(DiscTitle discTitle)
{
    //"BOXTITLE=<TEXT><CTRL_US>EDITION=<TEXT><CTRL_US>DESCRIPTION=<TEXT><CTRL_US>COVER=<TEXT><<CTRL_US><DATA_DISCS>"
    QByteArray message;
    message.append(QString("BOXTITLE"));
    message.append(Message::CTRL_EQUAL);
    message.append(discTitle.localTitle);

    message.append(Message::CTRL_US);
    message.append(QString("EDITION"));
    message.append(Message::CTRL_EQUAL);
    message.append(discTitle.edition);

    message.append(Message::CTRL_US);
    message.append(QString("DESCRIPTION"));
    message.append(Message::CTRL_EQUAL);
    message.append(discTitle.description);

    message.append(Message::CTRL_US);
    message.append(QString("DATA_DISCS"));
    message.append(Message::CTRL_EQUAL);
    message.append(makeDataDiscs(discTitle.discs));

    message.append(Message::CTRL_US);
    message.append(QString("COVER"));
    message.append(Message::CTRL_EQUAL);
    message.append(discTitle.cover);

    return message;
}

QByteArray Message::makeDataDisc(DiscData discData)
{
    //"ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT><CTRL_US>RIPPED=<VALUE><CTRL_US>BOXTITLE=<TEXT><CTRL_US>EDITION=<TEXT><CTRL_US>DESCRIPTION=<TEXT><CTRL_US><DATA_DISCS>"
    QByteArray message;
    message.append(QString("ID"));
    message.append(Message::CTRL_EQUAL);
    message.append(discData.getId());

    message.append(Message::CTRL_US);
    message.append(QString("TITLE"));
    message.append(Message::CTRL_EQUAL);
    message.append(discData.getTitle());

    message.append(Message::CTRL_US);
    message.append(QString("COUNTRY"));
    message.append(Message::CTRL_EQUAL);
    message.append(discData.getCountry());

    message.append(Message::CTRL_US);
    message.append(QString("RIPPED"));
    message.append(Message::CTRL_EQUAL);
    message.append(discData.getAlreadyRipped()?"1":"0");

    message.append(Message::CTRL_US);
    message.append(makeDataDiscTitle(discData.discTitle));

    return message;
}
QByteArray Message::makeMovieDisc(MovieData movieData)
{
    //"ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT><CTRL_US>YEAR=<TEXT><CTRL_US>RIPPED=<VALUE>"
    QByteArray message;
    message.append(QString("ID"));
    message.append(Message::CTRL_EQUAL);
    message.append(movieData.id);
    message.append(Message::CTRL_US);
    message.append(QString("TITLE"));
    message.append(Message::CTRL_EQUAL);
    message.append(movieData.title);
    message.append(Message::CTRL_US);
    message.append(QString("COUNTRY"));
    message.append(Message::CTRL_EQUAL);
    message.append(movieData.country);
    message.append(Message::CTRL_US);
    message.append(QString("YEAR"));
    message.append(Message::CTRL_EQUAL);
    message.append(movieData.year);
    message.append(Message::CTRL_US);
    message.append(QString("RIPPED"));
    message.append(Message::CTRL_EQUAL);
    message.append(movieData.alreadyRipped?"1":"0");
    return message;
}
QByteArray Message::getMessage(int messageId,QString messageText)
{

    QByteArray message;
    message.append(Message::CTRL_STX);

    switch(messageId)
    {
    case Message::START:
        message.append(Message::MSG_START);
        message.append(Message::CTRL_RS);
        message.append(messageText);
        break;
    case Message::STOP:
        message.append(Message::MSG_STOP);
        break;
    case Message::STATUS_READY:
        message.append(Message::MSG_STATUS_READY);
        break;
    case Message::STATUS_WORKING:
        message.append(Message::MSG_STATUS_WORKING);
        break;
    case Message::STATUS_DONE:
        message.append(Message::MSG_STATUS_DONE);
        break;
    case Message::DISC_DATA_UNKNOWN:
        message.append(Message::MSG_DISC_DATA_UNKNOWN);
        break;
    case Message::MOVIE_DATA_UNKNOWN:
        message.append(Message::MSG_MOVIE_DATA_UNKNOWN);
        break;
    case Message::SEARCH_MOVIE_DATA:
        message.append(Message::MSG_SEARCH_MOVIE_DATA);
        message.append(Message::CTRL_RS);
        message.append(messageText);
        break;
    case Message::SEARCH_DISC_TITLE_DATA:
        message.append(Message::MSG_SEARCH_DISC_TITLE_DATA);
        message.append(Message::CTRL_RS);
        message.append(messageText);
        break;
    }

    message.append(Message::CTRL_ETX);
    return message;
}
QByteArray Message::getMessageMSG(QByteArray messageText)
{
    QByteArray result;
    if(messageText.contains(Message::CTRL_STX))
    {
        result = messageText.mid(
                    messageText.indexOf(Message::CTRL_STX)+1,
                    1
                    );
    }

    return result;

}
MovieData Message::getMessageMovieData(QByteArray message)
{
    //ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT><CTRL_US>YEAR=<TEXT>CTRL_US>TYPE=<TEXT>
    MovieData result;
    QByteArray text(getMessageText(message));
    QListIterator<QByteArray> it(text.split(Message::CTRL_US));
    while(it.hasNext())
    {
        QListIterator<QByteArray> itemIt(it.next().split(Message::CTRL_EQUAL));
        if(itemIt.hasNext())
        {
            QByteArray attr(itemIt.next());
            if(itemIt.hasNext())
            {
                if(attr=="ID")
                    result.id=itemIt.next();
                else if(attr=="TITLE")
                    result.title=itemIt.next();
                else if(attr=="COUNTRY")
                    result.country=itemIt.next();
                else if(attr=="YEAR")
                    result.year=itemIt.next();
                else if(attr=="TYPE")
                    result.type=itemIt.next();
            }
        }
    }
    return result;
}
QList<MovieData> Message::getMessageMovieDataList(QByteArray message)
{
    //,ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT>,ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT>,...,n
    QList<MovieData> result;
    QByteArray text(getMessageText(message));
    QListIterator<QByteArray> it(text.split(Message::CTRL_RS));
    while(it.hasNext())
    {
        result.push_back(Message::getMessageMovieData(it.next()));
    }
    return result;
}

DiscData Message::getMessageDiscData(QByteArray message)
{
    //DATA_START = "ID=<TEXT><CTRL_US>IDA=<TEXT><CTRL_US>IDB=<TEXT>";
    DiscData result;
    Disc disc;
    QByteArray text(getMessageText(message));
    QListIterator<QByteArray> it(text.split(Message::CTRL_US));
    while(it.hasNext())
    {
        QListIterator<QByteArray> itemIt(it.next().split(Message::CTRL_EQUAL));
        if(itemIt.hasNext())
        {
            QByteArray attr(itemIt.next());
            if(itemIt.hasNext())
            {
                if(attr=="ID")
                {
                    result.setId(itemIt.next());
                }
                else if(attr=="ADULT")
                {
                    QString parental = itemIt.next();
                    bool parentalControl = (parental != "0");
                    result.setParentalControl(parentalControl);
                }
                else if(attr=="TITLE")
                {
                    result.setTitle(itemIt.next());
                }
                else if(attr=="COUNTRY")
                {
                    result.setCountry(itemIt.next());
                }
                else if(attr=="IDA")
                {
                    disc.discIdSideA = itemIt.next();
                }
                else if(attr=="IDB")
                {
                    disc.discIdSideB = itemIt.next();
                }
                else if(attr=="TYPE")
                {
                    result.type = itemIt.next();
                }
            }
        }
    }
    result.discTitle.discs.append(disc);
    return result;
}
QList<DiscData> Message::getMessageDiscDataList(QByteArray message)
{
    //,ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT>,ID=<TEXT><CTRL_US>TITLE=<TEXT><CTRL_US>COUNTRY=<TEXT>,...,n
    QList<DiscData> result;
    QByteArray text(getMessageText(message));
    QListIterator<QByteArray> it(text.split(Message::CTRL_RS));
    while(it.hasNext())
    {
        result.push_back(Message::getMessageDiscData(it.next()));
    }
    return result;
}

QByteArray Message::getMessageText(QByteArray messageText)
{
    qDebug()<<"Message::getMessageText(QByteArray messageText):"<<messageText;
    QByteArray result;
    if(messageText.contains(Message::CTRL_RS))
    {
        result = messageText.mid(
                    messageText.indexOf(Message::CTRL_RS)+1,
                    messageText.length()-(messageText.indexOf(Message::CTRL_RS)+1)-1
                    );
    }
    qDebug()<<"result:"<<result;
    return result;
}
